//
// Copyright (C) [2024] Xingyun Integrated Circuit, Inc.
//
// GreenCode was a private technology asset of Xingyun Integrated Circuit， Inc （Confidential）
//  Author: Shawn.Tan
//  Date : 2025.10.28
//
//  History : Initial Version 2025.10.28
//
//
#include "PageTableAllocator.h"

#include "Constraint.h"
#include "GenException.h"
#include "Log.h"
#include "PaGenerator.h"

using namespace std;

namespace Green {

  PageTableAllocator::PageTableAllocator(EMemBankType bankType)
    : mMemoryBank(bankType), mpAllocated(nullptr)
  {
    mpAllocated = new ConstraintSet();
  }

  PageTableAllocator::~PageTableAllocator()
  {
    delete mpAllocated;
  }

  bool PageTableAllocator::AllocatePageTableBlock(uint64 align, uint64 size, const ConstraintSet* usable, const ConstraintSet* range, uint64& start)
  {
    bool allocated = true;
    PaGenerator pa_gen(usable);
    try
    {
      bool is_instr = false;
      start = pa_gen.GenerateAddress(align, size, is_instr, range);
    }
    catch (const ConstraintError& alloc_err)
    {
      LOG(notice) << "{PageTableAllocator::AllocatePageTableBlock} out of page table space allocating with align: 0x" << hex << align << " size: 0x" << size << ", Error is " << alloc_err.what() << endl;
      allocated = false;
    }

    if (allocated)
    {
      uint64 pt_end = start + (size - 1);
      LOG(notice) << "{PageTableAllocator::AllocatePageTableBlock} Allocated page table at 0x" << hex << start << "-0x" << pt_end << " align 0x" << align << " from memory bank " << EMemBankType_to_string(mMemoryBank) << endl;
      mpAllocated->AddRange(start, pt_end);
    }
    return allocated;
  }
}
